package service

import (
	ClickHouse "gin/database"
	"gin/model"
	"gin/types"
	"gorm.io/gorm"
	"time"
)

type TaskAbnormal struct {
}

func (d *TaskAbnormal) Count(req types.AbnormalCountReq, tenantId int64) (res types.AbnormalCountRes, err error) {
	var s, e int64
	if req.StartTime > 0 {
		s = req.StartTime
	} else {
		var todayStart = time.Now().Format("2006-01-02")
		todayStartUnix, err := time.ParseInLocation("2006-01-02", todayStart, time.Local)
		if err != nil {
			return res, err
		}
		s = todayStartUnix.Unix()
	}

	if req.EndTime > 0 {
		e = req.EndTime
	} else {
		e = s + 60*60*24
	}

	//未处理 包含今日未处理和今日审核不通过
	// 该统计遇到的bug :1. 只记录取消状态,没有判定task_deprecate_data 2.只记录task_deprecate_data 来判定取消 (待办任务没有task_deprecate_data) 3.连接delay_order_task今日审核不通过为取的最新数据(因为可以重复发起审批)
	delayOrderModuleId := ModuleByCode("delay_order_task").Id
	noDealDB := ClickHouse.DB.Model(&model.Task{}).
		Joins("left join (select task_id,id,type from delay_order_task where project_id = ? and ((original_plan_time BETWEEN ? AND ? AND abnormal_info = 'not_done') or (plan_delivery_time BETWEEN ? AND ? AND abnormal_info = 'not_delivery')) order by task_id,id desc limit 1 by task_id) delay_task on task.id = delay_task.task_id", req.ProjectId, s, e, s, e).
		Joins("left join review_request on review_request.link_id = delay_task.id and review_request.module_id = ?", delayOrderModuleId)
	d.AbnormalFilter(noDealDB, req, tenantId)
	err = noDealDB.Where("task.project_id = ? and task.step_type <> 'step_category' and ("+
		"(delay_task.id = 0 and ((simpleJSONExtractInt(task.json,'task_status') not in (8,7,3) and JSONLength(JSONExtractString(task.json, 'task_deprecate_data')) = 0 and task.plan_end_time BETWEEN ? AND ?) or (simpleJSONExtractInt(task.json,'task_status') not in (7,3)  and JSONLength(JSONExtractString(task.json, 'task_deprecate_data')) = 0 and task.plan_delivery_time BETWEEN ? AND ?))) or"+
		"(delay_task.id <> 0 and review_request.is_reviewed = 'yes' and review_request.is_pass = 'no'))", req.ProjectId, s, e, s, e).
		Pluck("count(DISTINCT task.id)", &res.InWait).Error

	if err != nil {
		return
	}

	//已经申请延期通过的
	reviewRequestDB := ClickHouse.DB.Model(&model.Task{}).
		Joins("left join (select task_id,id,type from delay_order_task where project_id = ? and ((original_plan_time BETWEEN ? AND ? AND abnormal_info = 'not_done') or (plan_delivery_time BETWEEN ? AND ? AND abnormal_info = 'not_delivery')) order by task_id,id desc limit 1 by task_id) delay_task on task.id = delay_task.task_id", req.ProjectId, s, e, s, e).
		Joins("join review_request on review_request.link_id = delay_task.id and review_request.module_id = ?", delayOrderModuleId)
	d.AbnormalFilter(reviewRequestDB, req, tenantId)
	err = reviewRequestDB.Where("task.project_id = ? and task.step_type <> 'step_category'", req.ProjectId, s, e, s, e).
		Where("delay_task.type = 'request_delay' and review_request.is_reviewed = 'yes' and review_request.is_pass = 'yes'").
		Pluck("count(DISTINCT delay_task.task_id)", &res.MarkedDelay).Error

	if err != nil {
		return
	}

	//已标记今日完成
	todayDoneDB := ClickHouse.DB.Model(&model.Task{}).
		Joins("join delay_order_task on task.id = delay_order_task.task_id")
	d.AbnormalFilter(todayDoneDB, req, tenantId)
	err = todayDoneDB.Where("task.project_id = ? and task.step_type <> 'step_category' and (delay_order_task.original_plan_time BETWEEN ? AND ? OR delay_order_task.plan_delivery_time BETWEEN ? AND ?)", req.ProjectId, s, e, s, e).
		Where("delay_order_task.type = 'today_done'").
		Pluck("count(DISTINCT delay_order_task.task_id)", &res.MarkedToday).Error

	if err != nil {
		return
	}

	//处理中
	dealDB := ClickHouse.DB.Model(&model.Task{}).
		Joins("join delay_order_task on task.id = delay_order_task.task_id").
		Joins("join delay_order on delay_order.id = delay_order_task.delay_order_id").
		Joins("join review_request on review_request.link_id = delay_order_task.id and review_request.module_id = ?", delayOrderModuleId)
	d.AbnormalFilter(dealDB, req, tenantId)
	err = dealDB.Where("delay_order.project_id = ? and task.step_type <> 'step_category' and (delay_order_task.original_plan_time BETWEEN ? AND ? OR delay_order_task.plan_delivery_time BETWEEN ? AND ?)", req.ProjectId, s, e, s, e).
		Where("delay_order_task.type = 'request_delay' and review_request.is_reviewed = 'no'").
		Pluck("count(DISTINCT delay_order_task.task_id)", &res.InProgress).Error

	if err != nil {
		return
	}

	//今日内异常任务 = 未处理+以申请延期
	totalDB := ClickHouse.DB.Model(&model.Task{}).
		Joins("left join delay_order_task on task.id = delay_order_task.task_id").
		Joins("left join review_request on review_request.id = delay_order_task.id and review_request.module_id = ?", delayOrderModuleId)
	d.AbnormalFilter(totalDB, req, tenantId)
	err = totalDB.Where("task.project_id = ? and task.step_type <> 'step_category' and ("+
		"(delay_order_task.id = 0 and (simpleJSONExtractInt(task.json,'task_status') not in (8,7,3) and JSONLength(JSONExtractString(task.json, 'task_deprecate_data')) = 0 and task.plan_end_time BETWEEN ? AND ?) or (simpleJSONExtractInt(task.json,'task_status') not in (7,3) and JSONLength(JSONExtractString(task.json, 'task_deprecate_data')) = 0 and task.plan_delivery_time BETWEEN ? AND ?)) or"+
		"(delay_order_task.id <> 0 and ((delay_order_task.type = 'request_delay' and ((delay_order_task.original_plan_time BETWEEN ? AND ? AND abnormal_info = 'not_done') or (delay_order_task.plan_delivery_time BETWEEN ? AND ? AND abnormal_info = 'not_delivery'))) or"+
		"(delay_order_task.type = 'today_done' and ((delay_order_task.original_plan_time BETWEEN ? AND ?) or (delay_order_task.plan_delivery_time BETWEEN ? AND ?))))))", req.ProjectId, s, e, s, e, s, e, s, e, s, e, s, e).
		Pluck("count(DISTINCT task.id)", &res.Total).
		Error

	return
}

func (d *TaskAbnormal) AbnormalFilter(DB *gorm.DB, req types.AbnormalCountReq, tenantId int64) {
	//部门筛选
	if req.DepartmentId > 0 {
		DB = DB.
			Joins("join task_member on task_member.task_id = task.id").
			Joins("join user on user.id = task_member.partner").
			Joins("LEFT JOIN im_user on user.union_id = im_user.id").
			Joins("LEFT JOIN tenant_user on user.union_id = tenant_user.user_id").
			Where("tenant_user.department_id = ? and tenant_user.tenant_id = ? and im_user.active = ?", req.DepartmentId, tenantId, 1)
	}

	// 环节筛选
	if len(req.StepCategoryId) > 0 {
		DB = DB.Joins("join task_relation_tag on task_relation_tag.task_id = task.id and task_relation_tag.link_module_code in ('step_category','show_step_category')").
			Where("task_relation_tag.link_id in ?", req.StepCategoryId)
	}
}
